using System;
using System.Collections.Generic;
using NUnit.Framework;
using UseCaseManager.BO;

namespace UseCaseManager.Test.BO
{
    public class TestUtilsDrop
    {
        /// <summary>
        /// Creates a new saved Drop with a random value assigned to every property
        /// </summary>
        public static Drop CreateSavedDrop()
        {
            return CreateSavedDrop(null);
        }

        /// <summary>
        /// Creates a new saved Drop with a random value assigned to every property
        /// </summary>
        public static Drop CreateSavedDrop(Release release)
        {
            Drop drop = CreateUnsavedValidDrop(release);
            drop.Save();
            return drop;
        }

        public static Drop CreateUnsavedValidDrop(Release release)
        {
            Drop drop = new Drop
                            {
                                StartDate = TestUtils.GetRandomDate(),
                                EndDate = TestUtils.GetRandomDate(),
                                Name = TestUtils.GetRandomString(),
                                ReleaseID = release == null ? Guid.NewGuid() : release.ReleaseID
                            };
            return drop;
        }

        /// <summary>
        /// Creates a new unsaved Drop with a random value assigned to every property
        /// </summary>
        public static Drop CreateUnsavedValidDrop()
        {
            return CreateUnsavedValidDrop(null);
        }

        /// <summary>
        /// Creates a new unsaved Drop where all properties are null, except ID properties
        /// and those with default values.  If there are compulsory properties without
        /// defaults, saving the object will throw an exception.
        /// </summary>
        public static Drop CreateUnsavedDefaultDrop()
        {
            Drop drop = new Drop();
            return drop;
        }

        public static Drop CreateUnSavedDrop_WUseCases_BaselinePointsNull(int numberOfUseCases)
        {
            Drop drop = CreateUnsavedValidDrop();
            for (int i = 0; i < numberOfUseCases; i++)
            {
                int pointsAssigned = TestUtils.GetRandomInt(0, 50);
                TestUtilsUseCase.CreateUnsavedValidUseCase(drop, pointsAssigned);
            }
            return drop;
        }

        public static Drop CreateSavedDrop_WUseCases(int numberOfUseCases)
        {
            Drop drop = CreateSavedDrop();
            for (int i = 0; i < numberOfUseCases; i++)
            {
                int pointsAssigned = TestUtils.GetRandomInt(0, 50);
                TestUtilsUseCase.CreateSavedUseCase(drop, pointsAssigned);
            }
            return drop;
        }

        public static Drop CreateSavedDrop_WUseCases(int numberOfUseCases, out int expectedPointsAssigned)
        {
            expectedPointsAssigned = 0;
            Drop drop = CreateSavedDrop();
            for (int i = 0; i < numberOfUseCases; i++)
            {
                int pointsAssigned = TestUtils.GetRandomInt(0, 50);
                TestUtilsUseCase.CreateSavedUseCase(drop, pointsAssigned);
                expectedPointsAssigned += pointsAssigned;
            }
            return drop;
        }

        public static Drop CreateUnsavedDrop_WUseCases(int numberOfUseCases)
        {
            Drop drop = CreateUnsavedValidDrop();
            for (int i = 0; i < numberOfUseCases; i++)
            {
                int pointsAssigned = TestUtils.GetRandomInt(0, 50);

                drop.UseCases.Add(TestUtilsUseCase.CreateUnsavedValidUseCase(drop, pointsAssigned));
            }
            return drop;
        }

        public static Drop CreateSavedDrop_WUseCases_AssignedPointNull(int numberOfUseCases, out int expectedTotalPoints, out int expectedBaselineTotalPoints)
        {
            expectedTotalPoints = 0;
            expectedBaselineTotalPoints = 0;
            Drop drop = CreateSavedDrop();
            for (int i = 0; i < numberOfUseCases; i++)
            {
                int baselinePoints = TestUtils.GetRandomInt(0, 50);
                TestUtilsUseCase.CreateSavedUseCase(drop, null);
                expectedBaselineTotalPoints += baselinePoints;
            }
            return drop;
        }

        public static Drop CreateSavedDrop_WUseCases(Release release, int numberOfUseCases, out int expectedPointsAssigned)
        {
            Drop drop = CreateSavedDrop_WUseCases(numberOfUseCases, out expectedPointsAssigned);
            release.Drops.Add(drop);
            return drop;
        }

        public static void AssertUseCasesNotDirty(IEnumerable<UseCase> cases)
        {
            foreach (UseCase useCase in cases)
            {
                Assert.IsFalse(useCase.Status.IsDirty);
            }
        }

        public static Drop CreateSavedDrop_WUseCases_BaseLinePointsNull_AssignedPointsNull(int numberOfUseCases, out int expectedTotalPoints, out int expectedBaselineTotalPoints)
        {
            expectedTotalPoints = 0;
            expectedBaselineTotalPoints = 0;
            Drop drop = CreateSavedDrop();
            for (int i = 0; i < numberOfUseCases; i++)
            {
                TestUtilsUseCase.CreateSavedUseCase(drop, null);
            }
            return drop;
        }

        public static Drop CreateUnsavedValidDrop_WUseCases_SetAssignedPoints_SetUseCasesCompleted(int numberOfUseCases)
        {
            Drop drop = CreateUnsavedValidDrop();
            for (int i = 0; i < numberOfUseCases; i++)
            {
                UseCase useCase = TestUtilsUseCase.CreateUnsavedValidUseCase(drop);
                useCase.CompletedInDropID = drop.DropID;
            }
            return drop;
        }
    }
}